home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / machine / cchip.c < prev    next >
C/C++ Source or Header  |  2000-04-23  |  4KB  |  154 lines

  1. /***************************************************************************
  2.  
  3.    cchip.c
  4.  
  5. This file contains routines to interface with the Taito Controller Chip
  6. version 1. It's currently used by Superman and Mega Blade.
  7.  
  8. According to Richard Bush, the C-Chip is an encrypted Z80 which communicates
  9. with the main board as a protection feature.
  10.  
  11. In Superman, it's main purpose is to handle player inputs and coins and
  12. pass commands along to the sound chip.
  13.  
  14. The 68k queries the c-chip, which passes back $100 bytes of 68k code which
  15. are then executed in RAM. To get around this, we hack in our own code to
  16. communicate with the sound board, since we are familiar with the interface
  17. as it's used in Rastan and Super Space Invaders '91.
  18.  
  19. It is believed that the NOPs in the 68k code seem to be there to supply
  20. the necessary cycles to the cchip to switch banks.
  21.  
  22. This code requires that the player & coin inputs be in input ports 4-6.
  23.  
  24. ***************************************************************************/
  25.  
  26. #include "driver.h"
  27.  
  28. static int cchip1_bank;
  29. static int cchip[3];
  30.  
  31. /* Circular buffer, not FILO. Doh!. */
  32. static unsigned char cchip1_code[256] =
  33. {
  34.     0x48, 0xe7, 0x80, 0x80,                /* MOVEM.L D0/A0,-(A7)    ( Preserve Regs ) */
  35.     0x20, 0x6d, 0x1c, 0x40,                /* MOVEA.L ($1C40,A5),A0  ( Load sound pointer in A0 ) */
  36.     0x30, 0x2f, 0x00, 0x0c,                /* MOVE.W ($0C,A7),D0      ( Fetch sound number ) */
  37.     0x10, 0x80,                            /* MOVE.B D0,(A0)          ( Store it on sound pointer ) */
  38.     0x52, 0x88,                            /* ADDQ.W #1,A0              ( Increment sound pointer ) */
  39.     0x20, 0x3c, 0x00, 0xf0, 0x1c, 0x40, /* MOVE.L #$F01C40,D0      ( Load top of buffer in D0 ) */
  40.     0xb1, 0xc0,                            /* CMPA.L   D0,A0          ( Are we there yet? ) */
  41.     0x66, 0x04,                            /* BNE.S    *+$6          ( No, we arent, skip next line ) */
  42.     0x41, 0xed, 0x1c, 0x20,                /* LEA      ($1C20,A5),A0 ( Point to the start of the buffer ) */
  43.     0x2b, 0x48, 0x1c, 0x40,                /* MOVE.L A0,($1C40,A5)   ( Store new sound pointer ) */
  44.     0x4c, 0xdf, 0x01, 0x01,                /* MOVEM.L (A7)+, D0/A0      ( Restore Regs ) */
  45.     0x4e, 0x75,                            /* RTS                      ( Return ) */
  46. };
  47.  
  48. void cchip1_init_machine(void)
  49. {
  50.     /* init custom cchip values */
  51.     cchip[0] = cchip[1] = cchip[2] = 0;
  52.  
  53.     /* make sure we point to controls */
  54.     cchip1_bank = 0;
  55. }
  56.  
  57. READ_HANDLER( cchip1_r )
  58. {
  59.     int ret = 0;
  60.  
  61.     switch (offset)
  62.     {
  63.         case 0x000:
  64.             /* Player 1 */
  65.             if (cchip1_bank == 1)
  66.                 ret = cchip1_code[offset/2];
  67.             else
  68.                 if (cchip[0])
  69.                 {
  70.                     ret = cchip[0];
  71.                     cchip[0] = 0;
  72.                 }
  73.                 else
  74.                     ret = readinputport (4);
  75.             break;
  76.         case 0x002:
  77.             /* Player 2 */
  78.             if (cchip1_bank == 1)
  79.                 ret = cchip1_code[offset/2];
  80.             else
  81.                 if (cchip[1])
  82.                 {
  83.                     ret = cchip[1];
  84.                     cchip[1] = 0;
  85.                 }
  86.                 else
  87.                     ret = readinputport (5);
  88.             break;
  89.         case 0x004:
  90.             /* Coins */
  91.             logerror("cchip1_r (coin) pc: %06x, offset: %04x\n", cpu_get_pc(), offset);
  92.             if (cchip1_bank == 1)
  93.                 ret = cchip1_code[offset/2];
  94.             else
  95.                 if (cchip[2])
  96.                 {
  97.                     ret = cchip[2];
  98.                     cchip[2] = 0;
  99.                 }
  100.                 else
  101.                     ret = readinputport (6);
  102.             break;
  103.         case 0x802:
  104.             /* C-Chip ID */
  105.             ret =  0x01;
  106.             break;
  107.         case 0xc00:
  108.             ret =  cchip1_bank;
  109.             break;
  110.         default:
  111.             if (offset < 0x1f0 && cchip1_bank == 1)
  112.                 ret = cchip1_code[offset/2];
  113.             else
  114.             {
  115.                 logerror("cchip1_r offset: %04x\n", offset);
  116.                 ret = 0xff;
  117.             }
  118.             break;
  119.     }
  120.  
  121.     return ret;
  122. }
  123.  
  124. WRITE_HANDLER( cchip1_w )
  125. {
  126.     logerror("cchip1_w pc: %06x, %04x:%02x\n", cpu_get_pc(), offset, data);
  127.     switch (offset)
  128.     {
  129.         case 0x0000:
  130.             if ((data & 0xff) == 0x4a)
  131.                 cchip[0] = 0x47;
  132.             else cchip[0] = data;
  133.             break;
  134.  
  135.         case 0x0002:
  136.             if ((data & 0xff) == 0x46)
  137.                 cchip[1] = 0x57;
  138.             else cchip[1] = data;
  139.             break;
  140.  
  141.         case 0x0004:
  142.             if ((data & 0xff) == 0x34)
  143.                 cchip[2] = 0x4b;
  144.             else cchip[2] = data;
  145.             break;
  146.         case 0xc00:
  147.             cchip1_bank = data & 0x07;
  148.             break;
  149.         default:
  150.             break;
  151.     }
  152. }
  153.  
  154.